﻿using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using UIWindows.Domains;
using UIWindows.GlobalStatics;
using UIWindows.Models.Devices;
using UIWindows.Views;
using XingLucifer.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;

namespace UIWindows.ViewModels.DeviceConfig
{
    public class PLCTestVModel : Domains.ViewModelBase,IDeviceViewModel
    {
        public string DataType { get; set; }
        public IEnumerable<string> Foods
        {
            get => new string[] { "Int32", "UInt32", "Single", "Double", "Int16", "UInt16", "String" };
        }
        public PLCTestVModel()
        {

        }

        private string _value;
        /// <summary>
        /// 值
        /// </summary>
        public string Value
        {
            get { return _value; }
            set { SetProperty(ref _value, value); }
        }

        private string _logMessage;

        public string LogMessage
        {
            get { return _logMessage; }
            set { SetProperty(ref _logMessage, value); }
        }


        public DeviceClientModel DCModel { set; get; }

        public void SendModel(DeviceClientModel device)
        {
            if (device.TaskType != XingLucifer.IBase.Enums.TaskTypes.扫描信号)
            {
                return;
            }
            DCModel = device;
        }
        private XingLucifer.IBase.IDevices _devices;
        public int Address { get; set; }
        public Commands.DelegateCommand<Button> ViewToggle => new Commands.DelegateCommand<Button>(async sender =>
        {
            if (sender == null || DCModel == null)
            {
                return;
            }
            try
            {
                switch (sender.Content.ToString())
                {
                    case "连  接":
                        var _systemConfigStatic = ObjectContainer.ResolveSingleton<SystemConfigStatic>();
                        var token = new System.Threading.CancellationTokenSource();
                        ICommunication com = null;
                        EndianTypes endianTypes = EndianTypes.Fins;
                        switch (DCModel.DeviceType)
                        {
                            case DeviceTypes.NJ_FINS_PLC:
                                endianTypes = EndianTypes.Fins;
                                break;
                            case DeviceTypes.Modbus_TCP_ABCD:
                                endianTypes = EndianTypes.Modbus_ABCD;
                                break;
                            case DeviceTypes.Modbus_TCP_BADC:
                                endianTypes = EndianTypes.Modbus_BADC;
                                break;
                            case DeviceTypes.Modbus_TCP_DCBA:
                                endianTypes = EndianTypes.Modbus_DCBA;
                                break;
                            case DeviceTypes.Modbus_TCP_CDAB:
                                endianTypes = EndianTypes.Modbus_CDAB;
                                break;
                        }
                        com = new TCPCom(_systemConfigStatic.SCM.FinsIP, DCModel.IPCOM, DCModel.Port, DCModel.DeviceType, DCModel.Index, DCModel.TaskType, DCModel.ServiceName, token, endianTypes);
                        _devices = EquipmentFactory.NewSocketDevice(_systemConfigStatic.SCM.FinsIP, DCModel.IPCOM, DCModel.Port, DCModel.DeviceType, DCModel.Index, DCModel.TaskType, DCModel.ServiceName, token, com);
                        if (await Task.Run(() => _devices.Open()))
                        {
                            AddLog("打开通信成功");
                            sender.Content = "关 闭";
                        }
                        else
                        {
                            _devices.Close();
                            AddLog("打开通信失败");
                        }
                        break;
                    case "读  取":
                        Value = GetValueConversion();
                        break;
                    case "发  送":
                        object value = ToValueConversion();
                        if (_devices.WriteSingle(value, Address, 0, 32))
                        {
                            AddLog("发送成功");
                        }
                        else
                        {
                            AddLog("发送失败");
                        }
                        break;
                    case "关 闭":
                        LogMessage = default;
                        sender.Content = "连  接";
                        _devices?.Close();
                        break;
                    case "读  类":
                        Models.Interact.PLCSignalModel model = new Models.Interact.PLCSignalModel(2, 16);
                        _ = _devices.ReadClass(Address, model);
                        AddLog(System.Text.Json.JsonSerializer.Serialize(model));
                        break;
                    case "写  类":
                        TestModel testModel = new TestModel()
                        {
                            One = 256,
                            Two = 55,
                            Lpd = true,
                        };
                        if (_devices.WriteClass(testModel, Address, 0))
                        {
                            AddLog("写类成功");
                        }
                        else
                        {
                            AddLog("写类失败");
                        }
                        break;
                }
            }
            catch (Exception ex)
            {
                AddLog($"异常：{ex}");
            }
        });
        public class TestModel
        {
            public ushort One { get; set; }
            public ushort Two { get; set; }

            public bool Lpd { get; set; }
        }

        private object ToValueConversion()
        {
            try
            {
                switch (DataType)
                {
                    case "Int32": return Convert.ToInt32(Value);
                    case "UInt32": return Convert.ToUInt32(Value);
                    case "Single": return Convert.ToSingle(Value);
                    case "Double": return Convert.ToDouble(Value);
                    case "Int16": return Convert.ToInt16(Value);
                    case "UInt16": return Convert.ToUInt16(Value);
                    case "String": return Value;
                }
            }
            catch (Exception)
            {
            }
            return (ushort)1;
        }

        private string GetValueConversion()
        {
            switch (DataType)
            {
                case "Int32": return _devices.ReadSingle<int>(Address, 0).ToString();
                case "UInt32": return _devices.ReadSingle<uint>(Address, 0).ToString();
                case "Single": return _devices.ReadSingle<float>(Address, 0).ToString();
                case "Double": return _devices.ReadSingle<double>(Address, 0).ToString();
                case "Int16": return _devices.ReadSingle<short>(Address, 0).ToString();
                case "UInt16": return _devices.ReadSingle<ushort>(Address, 0).ToString();
                case "String": return _devices.ReadSingle<string>(Address, 32).ToString();
            }
            return "";
        }

        private void AddLog(string str) => LogMessage += $"{str}\r\n";
    }
}
